﻿using System.Collections.ObjectModel;
using LFSRecord2.Model;

namespace LFSRecord2.Structures
{
    public class InterpolateCacheHelper
    {
        public Collection<CustomPoint3DKeyFrameHelper> KeyFrames { get; private set; }

        public InterpolateCacheHelper()
        {
            KeyFrames = new Collection<CustomPoint3DKeyFrameHelper>();
        }

        public Point3DFrameCacheObject GetValueAtTimeWithBezierTime(double timelineIndex, ref int startKeyFrame, ref double continueBezierTime)
        {
            Point3DFrameCacheObject fo = new Point3DFrameCacheObject();
            fo.BezierTime = continueBezierTime;

            CustomPoint3DKeyFrameHelper fromKey = new CustomPoint3DKeyFrameHelper(0, ((CustomPoint3DKeyFrameHelper)KeyFrames[0]).Value);
            CustomPoint3DKeyFrameHelper toKey = null;

            CustomPoint3DKeyFrameHelper kf;
            int a;
            double lastBezierTime = 0;
            for (a = startKeyFrame; a < KeyFrames.Count; a++)
            {
                kf = (CustomPoint3DKeyFrameHelper)KeyFrames[a];
                if (timelineIndex < kf.NormalizedTime)
                {
                    toKey = kf;
                    break;
                }
                fromKey = kf;
                fo.BezierTime += kf.BezierTime;
                lastBezierTime = kf.BezierTime;
            }
            startKeyFrame = a - 1;
            if (startKeyFrame < 0)
                startKeyFrame = 0;
            continueBezierTime = fo.BezierTime - lastBezierTime;

            // Hold value? (time is beyond last keyframe)
            if (toKey == null)
            {
                fo.Value = fromKey.Value;
                return fo;
            }

            //Debug.WriteLine("FrameNum from and to : {0}, {1} - {2}", fromKey.NormalizedTime, toKey.NormalizedTime, timelineIndex);

            // Interpolate value
            fo.Value = CustomPoint3DInterpolation.InterpolateLinear(fromKey, toKey, timelineIndex);

            return fo;
        }
    }
}
